package com.sky.config;

import com.sky.interceptor.JwtTokenAdminInterceptor;
//import jdk.jpackage.internal.Log;
import com.sky.json.JacksonObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.List;

/**
 * 配置类，注册web层相关组件
 */
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {

    @Autowired
    private JwtTokenAdminInterceptor jwtTokenAdminInterceptor;

    /**
     * 注册自定义拦截器
     *
     * @param registry
     */
    protected void addInterceptors(InterceptorRegistry registry) {
        log.info("开始注册自定义拦截器...");
        registry.addInterceptor(jwtTokenAdminInterceptor)
                .addPathPatterns("/admin/**")
                .excludePathPatterns("/admin/employee/login");
    }

    /**
     * 通过knife4j生成接口文档
     * @return
     */

//    这里其实是把原来的接口文档的代码再复制了一次，然两段代码分别执行
//    不同的操作，比方说这个就是执行扫描的管理端的代码，然后下面的执行的是用户端的代码
//    并且还给他们的分组起了不同的名字

    @Bean
    public Docket docket1() {

        log.info("准备生成接口文档...");
        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("苍穹外卖项目接口文档")
                .version("2.0")
                .description("苍穹外卖项目接口文档")
                .build();
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .groupName("管理端接口")
                .apiInfo(apiInfo)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.sky.controller.admin"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }

    /**
     * 通过knife4j生成接口文档
     * @return
     */
    @Bean
    public Docket docket2() {

        log.info("准备生成接口文档...");
        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("苍穹外卖项目接口文档")
                .version("2.0")
                .description("苍穹外卖项目接口文档")
                .build();
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .groupName("用户端接口")
                .apiInfo(apiInfo)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.sky.controller.user"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }

    /**
     * 设置静态资源映射
     * @param registry
     */
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        log.info("开始设置静态资映射...");

        registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }


    /**
     *
     *扩展spring MVC框架的消息转化器
     *
     * @param converters
     */

//    好呀，让我们把这段代码想象成一个信息快递站的升级过程。
//    第一步：创建新的快递员
//“MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter ();” 就像是在快递站里新招募了一个特别的快递员。这个快递员的任务就是在网络世界中传递信息，特别是要把 Java 世界里的东西送到 JSON 世界去，或者把 JSON 世界的东西带回到 Java 世界。
//    第二步：给快递员配备超级工具
//“converter.setObjectMapper (new JacksonObjectMapper ());” 这里呢，就相当于给这个快递员配备了一个超级工具。这个工具（JacksonObjectMapper）非常厉害，它知道怎么把 Java 世界里的各种复杂的东西整理成 JSON 世界能理解的形式，就像把一堆形状各异的包裹打包成统一的、容易运输的箱子。同时，当 JSON 世界的东西送过来时，它也能准确地把这些箱子打开，还原成 Java 世界里的东西。
//    第三步：让新快递员上岗
//“converters.add (0, converter);” 这就像是把这个新快递员安排到快递站的重要岗位上。把他放在第一位（索引为 0），这样当有任务的时候，他会优先被派出去干活。这样一来，整个信息快递站（Spring MVC 的消息转换系统）就能更高效地在 Java 和 JSON 两个世界之间传递信息啦。
//


    @Override
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {

//        创建一个消息转化器的对象
        MappingJackson2HttpMessageConverter converter=new MappingJackson2HttpMessageConverter();
//        为消息转化器设置一个对象转化器，对象转化器可以将java序列化为json数据
//        JacksonObjectMapper就像是一个 “规则手册”。它里面定义了如何将 Java 对象转换为 JSON 数据以及
//        如何将 JSON 数据转换回 Java 对象的具体规则。
//        比如，它规定了日期和时间类型的数据在转换时应该采用什么样的格式，就像给快递包裹贴上特定
//        的标签，让接收方能够正确识别和处理。
//        同时，它也可以包含一些其他的注意事项，比如在遇到未知属性时
//        该如何处理（是报错还是忽略），就像快递员在遇到特殊情况时知道该怎么做才能确保包裹顺利送达。
//        总之，JacksonObjectMapper为消息转换器提供了一套
//        明确的转换规则和处理方式，确保数据在不同格式之间的转换能够准确、高效地进行。
//
        converter.setObjectMapper(new JacksonObjectMapper());
//        将自己的消息转化器加入容器中
        converters.add(0,converter);

    }
}
